import java.io.IOException;
import java.net.BindException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 类名：B服务器
 * 描述：创建一个网络聊天室服务器程序，描绘服务器界面，并与客户端建立联系
 */
public class B服务器 extends Thread {
    D服务器窗口 serverFrame = null;
    ServerSocket serverSocket = null; // 创建服务器端套接字

    public boolean bServerIsRunning = false;

    public B服务器() {
        try {
            serverSocket = new ServerSocket(C常量.SERVER_PORT); // 启动服务
            bServerIsRunning = true;

            serverFrame = new D服务器窗口();
            getServerIP(); // 得到并显示服务器端IP
            System.out.println("Server Port is:" + C常量.SERVER_PORT);
            serverFrame.taLog.setText("服务器已经启动...");
            while (true) {
                Socket socket = serverSocket.accept(); // 监听客户端的连接请求，并返回客户端socket
                new ServerProcess(socket, serverFrame); // 创建一个新线程来处理与该客户的通讯
            }
        } catch (BindException e) {
            System.out.println("端口使用中....");
            System.out.println("请关掉相关程序并重新运行服务器！");
            System.exit(0);
        } catch (IOException e) {
            System.out.println("[ERROR] Cound not start server." + e);
        }

        this.start(); // 启动线程
    }
/*B服务器 类继承了 Thread 类，用于创建服务器程序并处理客户端的连接请求。
声明变量 serverFrame 和 serverSocket，分别用于服务器界面和服务器套接字。
声明布尔变量 bServerIsRunning，用于表示服务器是否正在运行。
B服务器 类的构造函数，用于启动服务器程序。
在构造函数中，通过 ServerSocket 类创建服务器套接字并绑定到指定端口 Constants.SERVER_PORT，启动服务。
将变量 bServerIsRunning 设置为 true 表示服务器正在运行。
创建服务器界面 ServerFrame 的实例，并赋值给 serverFrame 变量。
调用 getServerIP() 方法，获取服务器的主机名和IP地址，并在服务器界面中显示。
输出服务器端口号到控制台。
设置服务器界面的日志文本框 taLog 的显示文本为 "服务器已经启动..."。
进入无限循环，监听客户端的连接请求。
当有客户端连接请求到达时，通过 serverSocket.accept() 方法接受连接并返回客户端的套接字 Socket。
创建一个新的线程 ServerProcess 来处理与该客户端的通信，传递客户端套接字和服务器界面作为参数。
在 B服务器 的构造函数中，如果捕获到 BindException 异常，则表示端口已被占用，输出提示信息并退出程序。
在 B服务器 的构造函数中，如果捕获到 IOException 异常，则表示无法启动服务器，输出错误信息。
调用 start() 方法启动线程。*/
    /**
     * 获取服务器的主机名和IP地址
     */
    public void getServerIP() {
        try {
            InetAddress serverAddress = InetAddress.getLocalHost();
            byte[] ipAddress = serverAddress.getAddress();

            serverFrame.txtServerName.setText(serverAddress.getHostName());
            serverFrame.txtIP.setText(serverAddress.getHostAddress());
            serverFrame.txtPort.setText(String.valueOf(C常量.SERVER_PORT));

            System.out.println("Server IP is:" + (ipAddress[0] & 0xff) + "."
                    + (ipAddress[1] & 0xff) + "." + (ipAddress[2] & 0xff) + "."
                    + (ipAddress[3] & 0xff));
        } catch (Exception e) {
            System.out.println("###Cound not get Server IP." + e);
        }
    }
/*getServerIP() 方法用于获取服务器的主机名和IP地址，并在服务器界面中显示。
使用 InetAddress.getLocalHost() 方法获取本地主机的 InetAddress 实例。
调用 getAddress() 方法获取主机的IP地址的字节数组。
在服务器界面中的文本框 txtServerName、txtIP 和 txtPort 中分别显示主机名、IP地址和服务器端口。
将服务器的IP地址以字符串的形式输出到控制台。*/
    /**
     * main方法，实例化服务器端程序
     *
     * @param args
     */
    public static void main(String args[]) {
        new B服务器();
    }
}
/*main 方法，用于实例化服务器端程序。
创建 B服务器 类的实例对象。*/